package cn.com.nes.common.baiduface;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class BaiduFace {
	
	private AccessTokenManager tokenManager;
	private Integer planId;
	
	public BaiduFace(String clientId, String clientSecret, Integer planId) {
		this.tokenManager = new AccessTokenManager(clientId, clientSecret);
		this.planId = planId;
	}
	
	/**
	 * 一个VerifyToken代表一个认证流程
	 * @return
	 */
	public String generateVerifyToken() {
		ObjectNode result = BaiduApis.getVerifyToken(tokenManager.getAccessToken(), this.planId);
		if(result.has("success") && result.get("success").asBoolean()) {
			String verifyToken = result.get("result").get("verify_token").asText();
			return verifyToken;
		} else if(result.has("error_code")) {
			throw new RuntimeException(result.get("error_msg").asText() + " : " + result.get("error_code").asText());
		} else {
			throw new RuntimeException();
		}
	}
	
	public String generateUrl(String verifyToken, String successUrl, String failedUrl) {
		StringBuilder sb = new StringBuilder("https://brain.baidu.com/face/print/?token=");
		sb.append(verifyToken);
		try {
			if(StringUtils.hasText(successUrl)) {
				sb.append("&successUrl=").append(URLEncoder.encode(successUrl, "UTF-8"));
			}
			if(StringUtils.hasText(failedUrl)) {
				sb.append("&failedUrl=").append(URLEncoder.encode(failedUrl, "UTF-8"));
			}
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("", e);
		}
		return sb.toString();
	}
	
	public Map<String, Object> getResult(String verifyToken) {
		Map<String, Object> result = new LinkedHashMap<>();
		ObjectNode jsonObject = BaiduApis.getFaceDetail(tokenManager.getAccessToken(), verifyToken);
		
		result.put("success", jsonObject.get("success").asBoolean());
		if(jsonObject.hasNonNull("result")) {
			JsonNode jsonResult = jsonObject.get("result");
			
			if(jsonResult.hasNonNull("verify_result")) {
				Map<String, Object> verify = new LinkedHashMap<String, Object>();
				verify.put("score", jsonResult.get("verify_result").get("score").asDouble());
				verify.put("liveness_score", jsonResult.get("verify_result").get("liveness_score").asDouble());
				verify.put("spoofing", jsonResult.get("verify_result").get("spoofing").asDouble());
				result.put("verify_result", verify);
			}
			if(jsonResult.hasNonNull("idcard_images")) {
				Map<String, Object> idcardImages = new LinkedHashMap<String, Object>();
				idcardImages.put("front_base64", jsonResult.get("idcard_images").get("front_base64").asText());
				idcardImages.put("back_base64", jsonResult.get("idcard_images").get("back_base64").asText());
				result.put("idcard_images", idcardImages);
			}
			if(jsonResult.hasNonNull("idcard_confirm")) {
				Map<String, Object> idcardConfirm = new LinkedHashMap<String, Object>();
				idcardConfirm.put("idcard_number", jsonResult.get("idcard_confirm").get("idcard_number").asText());
				idcardConfirm.put("name", jsonResult.get("idcard_confirm").get("name").asText());
				result.put("idcard_confirm", idcardConfirm);
			}
			
		}
		if(jsonObject.hasNonNull("code")) {
			result.put("code", jsonObject.get("code").asInt());
		}
		if(jsonObject.hasNonNull("message")) {
			result.put("message", jsonObject.get("message").asText());
		}
		// 读取人脸图片接口
		jsonObject = BaiduApis.getFaceImage(tokenManager.getAccessToken(), verifyToken);
		Map<String, Object> faceImage = new LinkedHashMap<>();
		faceImage.put("success", jsonObject.get("success").asBoolean());
		if(jsonObject.hasNonNull("result")) {
			faceImage.put("faceImageUrl", jsonObject.get("result").get("image").asText());
			if(jsonObject.get("result").has("real_message")) {
				faceImage.put("real_message", jsonObject.get("result").get("real_message").asText());
			}
		}
		result.put("faceImage", faceImage);
		
		return result;
	}
	
	public Faceprint parser(String verifyToken) {
		Faceprint faceprint = new Faceprint();
		ObjectNode jsonObject = BaiduApis.getFaceDetail(tokenManager.getAccessToken(), verifyToken);
		faceprint.setResultDetail(jsonObject.toString());
		if(jsonObject.hasNonNull("result")) {
			JsonNode result = jsonObject.get("result");
			if(result.hasNonNull("idcard_images") && result.get("idcard_images").has("front_base64")) {
				String frontBase64 = result.get("idcard_images").get("front_base64").asText();
				if(StringUtils.hasText(frontBase64)) {
					faceprint.setIdcardImagesFront(Base64.decodeBase64(frontBase64));
				}
			}
			if(result.hasNonNull("idcard_images") && result.get("idcard_images").has("back_base64")) {
				String backBase64 = result.get("idcard_images").get("back_base64").asText();
				if(StringUtils.hasText(backBase64)) {
					faceprint.setIdcardImagesBack(Base64.decodeBase64(backBase64));
				}
			}
			if(result.hasNonNull("idcard_confirm")) {
				JsonNode idcardConfirm = result.get("idcard_confirm");
				if(idcardConfirm.has("idcard_number")) {
					faceprint.setIdcardNumber(idcardConfirm.get("idcard_number").asText());
				}
				if(idcardConfirm.has("name")) {
					faceprint.setIdcardName(idcardConfirm.get("name").asText());
				}
			}
		}
		
		if(jsonObject.has("success")) {
			faceprint.setSuccess(jsonObject.get("success").asBoolean());
		}
		if(jsonObject.has("code")) {
			faceprint.setCode(jsonObject.get("code").asInt());
		}
		if(jsonObject.has("message")) {
			faceprint.setMessage(jsonObject.get("message").asText());
		}

		jsonObject = BaiduApis.getFaceImage(tokenManager.getAccessToken(), verifyToken);
		faceprint.setResultSimple(jsonObject.toString());
		if(jsonObject.hasNonNull("result") && jsonObject.get("result").has("image")) {
			String image = jsonObject.get("result").get("image").asText();
			if(StringUtils.hasText(image)) {
				byte[] imageBytes = BaiduApis.getBytes(image);
				faceprint.setFaceImage(imageBytes);
			}
		}
		
		jsonObject = BaiduApis.getFaceStat(tokenManager.getAccessToken(), verifyToken);
		faceprint.setResultStat(jsonObject.toString());
		
		faceprint.setVerifyToken(verifyToken);
		return faceprint;
	}

}
